﻿/*
 * Rappelz: Endless Odyssey - The first free open source Rappelz server emulator
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Rappelz.GameServer
{
    public class TerrainSeamlessWorldInfo
    {

        public class FilenameMapInfo
        {
            public string m_strMapFileName;
            public int m_nWorldID;
        }

        public bool Initialize(string szSeamlessWorldInfoFileName, bool bMapFileCheck)
        {
            int nMapLayer;
            int nWorldMapID;
            int nTileCountPerSegment;
            float fTileLength;
            int nSegmentCountPerMap;
            int nMapCountY;
            float pStream;
            int nMapIndex;
            int nMapCountX;

            List<string> TextLines = new List<string>();

            this.Release();

            try
            {
                System.IO.StreamReader bw = new System.IO.StreamReader(Globals.AppPath + "\\resource\\NewMap\\" +  szSeamlessWorldInfoFileName);
                String row = bw.ReadLine();
                while (row != null)
                {
                    if(!String.IsNullOrEmpty(row) && !row.StartsWith(";") )
                        TextLines.Add(row);
                    row = bw.ReadLine();
                }
                bw.Close();
                bw.Dispose();
            }
            catch (System.Exception ex)
            {
            	Globals.Log.Fatal("Error Reading Map Info: {0} - {1}", szSeamlessWorldInfoFileName, ex);
                return false;
            }

            if(TextLines.Count <= 0)
                return false;
            fTileLength = 0.0f;
            pStream = 0.0f;
            nTileCountPerSegment = 0;
            nSegmentCountPerMap = 0;
            nMapCountX = 0;
            nMapCountY = 0;
            nMapLayer = 0;
            //nX = 0;
            string[] vars;
            FilenameMapInfo fnmi;

            foreach (string s in TextLines)
            {
                string[] lines = s.Split('=');
                if(lines.Length < 2)
                    continue;
                switch(lines[0])
                {
                    case "TILE_LENGTH":
                        fTileLength = Marshal.ToSingle(lines[1]);
                        break;

                    case "TILECOUNT_PER_SEGMENT":
                        nTileCountPerSegment = Marshal.ToInt32(lines[1]);
                        break;

                    case "SEGMENTCOUNT_PER_MAP":
                        nSegmentCountPerMap = Marshal.ToInt32(lines[1]);
                        break;

                    case "SETFOV":
                        pStream = Marshal.ToSingle(lines[1]);
                        break;

                    case "MAPLAYER":
                        nMapLayer = Marshal.ToInt32(lines[1]);
                        break;

                    case "MAPSIZE":
                        vars = lines[1].Split(',');
                        if (vars.Length != 2)
                            return false;
                        nMapCountX = Marshal.ToInt32(vars[0]);
                        nMapCountY = Marshal.ToInt32(vars[1]);
                        break;

                    case "MAPFILE":
                        vars = lines[1].Split(',');
                        if (vars.Length != 5)
                            return false;

                        nWorldMapID = Marshal.ToInt32(vars[4]);
                        nMapLayer = Marshal.ToInt32(vars[2]);
                        nMapIndex = Marshal.ToInt32(vars[0]) + (nMapCountX * Marshal.ToInt32(vars[1]));
                        fnmi = new FilenameMapInfo();
                        fnmi.m_nWorldID = nWorldMapID;
                        fnmi.m_strMapFileName = vars[3];
                        if (!this.m_FileNameMap.ContainsKey(nMapIndex))
                            this.m_FileNameMap.Add(nMapIndex, fnmi);
                        break;
                }
            }

            if (fTileLength <= 0.0f || nTileCountPerSegment <= 0 || nSegmentCountPerMap <= 0 || this.m_FileNameMap.Count == 0)
                return false;

            this.m_fTileLength = fTileLength;
            this.m_nTileCountPerSegment = nTileCountPerSegment;
            this.m_nSegmentCountPerMap = nSegmentCountPerMap;
            this.m_nMapLayer = nMapLayer;
            this.m_sizMapCount.width = nMapCountX;
            this.m_sizMapCount.height = nMapCountY;
            if (pStream > 0.0f)
                this.m_fFOV = pStream;

            if (!bMapFileCheck || (nMapCountY <= 0))
            {
//        LABEL_88:
                return true;
            }
/*
            while ( 1 )
            {
                nX = 0;
                if ( nMapCountX > 0 )
                    break;
        LABEL_87:
                ++nY;
                if ( nY >= nMapCountY )
                    return true;
            }
            while ( 1 )
            {
                CTerrainSeamlessWorldInfo::GetMapFileName(v37, &strMapFileName, nX, nY);
                LOBYTE(v71) = 13;
                if ( strMapFileName._Mysize )
                    break;
        LABEL_86:
                LOBYTE(v71) = 0;
                std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_Tidy(&strMapFileName, 1, 0);
                ++nX;
                if ( nX >= nMapCountX )
                    goto LABEL_87;
            }
            v41 = *&strMapFileName._Bx._Buf[0];
            if ( strMapFileName._Myres < 0x10 )
                v41 = &strMapFileName._Bx;
            v42 = v37->vfptr;
            *&strContent._Bx._Buf[8] = v41;
            v43 = v42->GetResourceStream(v37, v41);
            LODWORD(pStream) = v43;
            if ( !v43 )
                goto LABEL_101;
            v44 = *v43;
            *&strContent._Bx._Buf[8] = 56;
            *&strContent._Bx._Buf[4] = &header;
            v14 = (*(v44 + 4))(&header, 56, *&strContent._Bx._Buf[12]) == 56;
            v45 = *LODWORD(pStream);
            *&strContent._Bx._Buf[12] = 1;
            if ( !v14 )
            {
                (*v45)(*&strContent._Bx._Buf[12]);
                goto LABEL_101;
            }
            (*v45)();
            std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>(
                &strSign,
                header.szSign);
            LOBYTE(v71) = 14;
            if ( !std::basic_string<char_std::char_traits<char>_std::allocator<char>>::compare(&strSign, "nFlavor Map")
              && header.dwVersion == 21
              && header.nTileCountPerSegment == nTileCountPerSegment
              && header.nSegmentCountPerMap == nSegmentCountPerMap
              && fTileLength == header.fTileLength )
            {
                std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_Tidy(&strSign, 1, 0);
                goto LABEL_86;
            }
            std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_Tidy(&strSign, 1, 0);
        LABEL_101:
            v47 = &strMapFileName;
        LABEL_91:
            std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_Tidy(v47, 1, 0);
        LABEL_92:
            std::vector<std::basic_string<char_std::char_traits<char>_std::allocator<char>>_std::allocator<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>>::_Tidy(&TextLines);
            return 0;
*/

            return false;
        }

        public void Release()
        {
            this.m_fTileLength = 0.0f;
            this.m_nTileCountPerSegment = 0;
            this.m_nSegmentCountPerMap = 0;
            this.m_FileNameMap.Clear();
//            this.m_sizMapCount.___u1.height = 0;
//            this.m_sizMapCount.___u0.width = 0;
            this.m_nMapLayer = 0;

        }
// Function       :   public int GetTileCountPerSegment()
// Function       :   public int GetSegmentCountPerMap()
// Function       :   public float GetTileLength()
// Function       :   public const struct KSize & GetMapCount()
// Function       :   public int GetMapLayer()

        public string GetMapFileName(int nMapPosX, int nMapPosY)
        {
            return GetFileNameWithExt(nMapPosX, nMapPosY, "nfm");
        }

        public string GetScriptFileName(int nMapPosX, int nMapPosY)
        {
            return GetFileNameWithExt(nMapPosX, nMapPosY, "nfs");
        }

        public string GetLocationFileName(int nMapPosX, int nMapPosY)
        {
            return GetFileNameWithExt(nMapPosX,nMapPosY,"nfc");
        }

        public string GetAttributePolygonFileName(int nMapPosX, int nMapPosY)
        {
            return GetFileNameWithExt(nMapPosX, nMapPosY, "nfa");
        }

        public string GetFieldPropFileName(int nMapPosX, int nMapPosY)
        {
            return GetFileNameWithExt(nMapPosX, nMapPosY, "qpf");
        }

        public string GetMinimapImageFileName(int nMapPosX, int nMapPosY)
        {
            return GetFileNameWithExt(nMapPosX, nMapPosY, "bmp");
        }

        public string GetLQWaterFileName(int nMapPosX, int nMapPosY)
        {
            return GetFileNameWithExt(nMapPosX, nMapPosY, "nfw");
        }

        public int GetWorldID(int nMapPosX, int nMapPosY)
        {
            int nMapIndex = nMapPosX + (m_sizMapCount.width * nMapPosY);
            if (m_FileNameMap.ContainsKey(nMapIndex))
                return m_FileNameMap[nMapIndex].m_nWorldID;
            return -1;
        }

        public float GetFOV()
        {
            return m_fFOV;
        }

        public int m_nTileCountPerSegment;                      // 0x4
        public int m_nSegmentCountPerMap;                       // 0x8
        public float m_fTileLength;                             // 0xC
        public KSize m_sizMapCount = new KSize();               // 0x10
        public int m_nMapLayer;                               // 0x18
        public SortedDictionary<int, FilenameMapInfo> m_FileNameMap = new SortedDictionary<int, FilenameMapInfo>();

        public float m_fFOV;

        private string GetFileNameWithExt(int nMapPosX, int nMapPosY, string ext)
        {
            int nMapIndex = nMapPosX + (m_sizMapCount.width * nMapPosY);
            if (!m_FileNameMap.ContainsKey(nMapIndex))
                return "";
            return m_FileNameMap[nMapIndex].m_strMapFileName + "." + ext;
        }

    }

    public class KRect
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    public class KPoint
    {
        public int x;
        public int y;

    }

    public class KSize
    {
        public int width;
        public int cx;
        public int height;
        public int cy;
    }
}
